home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / mach / sun4c.md / utility.c < prev    next >
C/C++ Source or Header  |  1989-08-17  |  4KB  |  164 lines

  1. #ifdef sccsid
  2. static char     sccsid[] = "@(#)utility.c 1.7 88/02/08 SMI";
  3. #endif
  4.  
  5. /*
  6.  * Copyright (c) 1988 by Sun Microsystems, Inc.
  7.  */
  8.  
  9. /* Utility functions for Sparc FPU simulator. */
  10.  
  11. /*
  12.  * This whole file refuses to lint.
  13.  */
  14. #ifndef lint
  15. #include <sun4/fpu/fpu_simulator.h>
  16. #include <sun4/fpu/globals.h>
  17.  
  18. void
  19. _fp_read_vfreg(pf, n)
  20.     FPU_REGS_TYPE  *pf;    /* Old freg value. */
  21.     unsigned        n;    /* Want to read register n. */
  22.  
  23. {
  24.     *pf = _fp_current_pfregs->fpu_regs[n];
  25. }
  26.  
  27. void
  28. _fp_write_vfreg(pf, n)
  29.     FPU_REGS_TYPE  *pf;    /* New freg value. */
  30.     unsigned        n;    /* Want to read register n. */
  31.  
  32. {
  33.     _fp_current_pfregs->fpu_regs[n] = *pf;
  34. }
  35.  
  36. void
  37. fpu_normalize(pu)
  38.     unpacked       *pu;
  39.  
  40. /* Normalize a number.  Does not affect zeros, infs, or NaNs. */
  41.  
  42. {
  43.     if ((*pu).fpclass == fp_normal) {
  44.         if (((*pu).significand[0] | (*pu).significand[1] | (*pu).significand[2]) == 0) {    /* true zero */
  45.             (*pu).fpclass = fp_zero;
  46.             return;
  47.         }
  48.         while ((*pu).significand[0] == 0) {
  49.             (*pu).significand[0] = (*pu).significand[1];
  50.             (*pu).significand[1] = (*pu).significand[2];
  51.             (*pu).significand[2] = 0;
  52.             (*pu).exponent = (*pu).exponent - 32;
  53.         }
  54.         while ((*pu).significand[0] < 0x80000000) {
  55.             pu->significand[0] = pu->significand[0] << 1;
  56.             if (pu->significand[1] >= 0x80000000)
  57.                 pu->significand[0] += 1;
  58.             pu->significand[1] = pu->significand[1] << 1;
  59.             if (pu->significand[2] >= 0x80000000)
  60.                 pu->significand[1] += 1;
  61.             pu->significand[2] = pu->significand[2] << 1;
  62.             (*pu).exponent = (*pu).exponent - 1;
  63.         }
  64.     }
  65. }
  66.  
  67. void
  68. fpu_rightshift(pu, n)
  69.     unpacked       *pu;
  70.     int             n;
  71.  
  72. /* Right shift significand sticky by n bits.  */
  73.  
  74. {
  75.     if (n >= 66) {        /* drastic */
  76.         if (((*pu).significand[0] | (*pu).significand[1] | (*pu).significand[2]) == 0) {    /* really zero */
  77.             pu->fpclass = fp_zero;
  78.             return;
  79.         } else {
  80.             pu->significand[2] = 0x20000000;
  81.             pu->significand[1] = 0;
  82.             pu->significand[0] = 0;
  83.             return;
  84.         }
  85.     }
  86.     while (n >= 32) {    /* big shift */
  87.         if (pu->significand[2] != 0)
  88.             pu->significand[1] |= 1;
  89.         (*pu).significand[2] = (*pu).significand[1];
  90.         (*pu).significand[1] = (*pu).significand[0];
  91.         (*pu).significand[0] = 0;
  92.         n -= 32;
  93.     }
  94.     while (n > 0) {        /* small shift */
  95.         if (pu->significand[2] & 1)
  96.             pu->significand[2] |= 2;
  97.         pu->significand[2] = pu->significand[2] >> 1;
  98.         if (pu->significand[1] & 1)
  99.             pu->significand[2] |= 0x80000000;
  100.         pu->significand[1] = pu->significand[1] >> 1;
  101.         if (pu->significand[0] & 1)
  102.             pu->significand[1] |= 0x80000000;
  103.         pu->significand[0] = pu->significand[0] >> 1;
  104.         n -= 1;
  105.     }
  106. }
  107.  
  108. void
  109. fpu_set_exception(ex)
  110.     enum fp_exception_type ex;
  111.  
  112. /* Set the exception bit in the current exception register. */
  113.  
  114. {
  115.     _fp_current_exceptions |= 1 << (int) ex;
  116. }
  117.  
  118. void
  119. fpu_error_nan(pu)
  120.     unpacked       *pu;
  121.  
  122. {                /* Set invalid exception and error nan in *pu */
  123.  
  124.     fpu_set_exception(fp_invalid);
  125.     pu->significand[0] = 0xffffffff;
  126.     pu->significand[1] = 0xffffffff;
  127.     pu->sign = 0;        /* MC68881 always returns +NaN, so so do we. */
  128. }
  129.  
  130. #ifdef DEBUG
  131. void
  132. display_unpacked(pu)
  133.     unpacked       *pu;
  134.  
  135. /* Print out unpacked record.     */
  136.  
  137. {
  138.     (void) printf(" unpacked ");
  139.     if (pu->sign)
  140.         (void) printf("-");
  141.     else
  142.         (void) printf("+");
  143.  
  144.     switch (pu->fpclass) {
  145.     case fp_zero:
  146.         (void) printf("0");
  147.         break;
  148.     case fp_normal:
  149.         (void) printf("normal");
  150.         break;
  151.     case fp_infinity:
  152.         (void) printf("Inf");
  153.         break;
  154.     case fp_quiet:
  155.     case fp_signaling:
  156.         (void) printf("nan");
  157.         break;
  158.     }
  159.     (void) printf(" %X %X %X exponent %X \n", pu->significand[0], pu->significand[1], pu->significand[2],
  160.               pu->exponent);
  161. }
  162. #endif
  163. #endif /* lint */
  164.